package com.douyin.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.scheduling.annotation.Scheduled;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

@Slf4j
@Service
@RequiredArgsConstructor
public class MonitoringService {
    
    private final ParseRecordService parseRecordService;
    
    // 实时监控数据缓存
    private final Map<String, Object> realtimeMetrics = new ConcurrentHashMap<>();
    
    // 系统健康状态
    private final Map<String, Object> systemHealth = new ConcurrentHashMap<>();
    
    // 告警状态
    private final Set<String> activeAlerts = ConcurrentHashMap.newKeySet();
    
    // 性能计数器
    private final AtomicLong totalRequests = new AtomicLong(0);
    private final AtomicLong successRequests = new AtomicLong(0);
    private final AtomicLong failedRequests = new AtomicLong(0);
    private final Map<String, AtomicLong> errorCounts = new ConcurrentHashMap<>();
    
    /**
     * 获取实时监控数据
     */
    public Map<String, Object> getRealtimeMetrics() {
        Map<String, Object> metrics = new HashMap<>(realtimeMetrics);
        
        // 添加计数器数据
        metrics.put("totalRequests", totalRequests.get());
        metrics.put("successRequests", successRequests.get());
        metrics.put("failedRequests", failedRequests.get());
        metrics.put("successRate", calculateSuccessRate());
        metrics.put("errorDistribution", getErrorDistribution());
        
        // 添加系统指标
        metrics.put("systemHealth", new HashMap<>(systemHealth));
        metrics.put("activeAlerts", new ArrayList<>(activeAlerts));
        metrics.put("timestamp", LocalDateTime.now());
        
        return metrics;
    }
    
    /**
     * 记录请求指标
     */
    public void recordRequest(boolean success, String errorCode) {
        totalRequests.incrementAndGet();
        
        if (success) {
            successRequests.incrementAndGet();
        } else {
            failedRequests.incrementAndGet();
            if (errorCode != null) {
                errorCounts.computeIfAbsent(errorCode, k -> new AtomicLong(0)).incrementAndGet();
            }
        }
        
        updateRealtimeMetrics();
    }
    
    /**
     * 获取用户行为分析报告
     */
    public Map<String, Object> getUserBehaviorReport(LocalDateTime startTime, LocalDateTime endTime) {
        Map<String, Object> report = new HashMap<>();
        
        // 活跃时段分析
        Map<Integer, Long> hourlyActivity = analyzeHourlyActivity(startTime, endTime);
        report.put("hourlyActivity", hourlyActivity);
        
        // 用户留存分析
        Map<String, Object> retentionAnalysis = analyzeUserRetention(startTime, endTime);
        report.put("userRetention", retentionAnalysis);
        
        // 解析成功率趋势
        List<Map<String, Object>> successRateTrend = analyzeSuccessRateTrend(startTime, endTime);
        report.put("successRateTrend", successRateTrend);
        
        // 用户设备偏好
        Map<String, Long> devicePreference = analyzeDevicePreference(startTime, endTime);
        report.put("devicePreference", devicePreference);
        
        // 地理分布分析
        Map<String, Object> geoDistribution = analyzeGeographicalDistribution(startTime, endTime);
        report.put("geographicalDistribution", geoDistribution);
        
        return report;
    }
    
    /**
     * 系统健康检查
     */
    public Map<String, Object> performHealthCheck() {
        Map<String, Object> health = new HashMap<>();
        
        // 数据库连接检查
        boolean dbHealthy = checkDatabaseHealth();
        health.put("database", Map.of("status", dbHealthy ? "healthy" : "unhealthy", "timestamp", LocalDateTime.now()));
        
        // 解析服务检查
        boolean parseServiceHealthy = checkParseServiceHealth();
        health.put("parseService", Map.of("status", parseServiceHealthy ? "healthy" : "unhealthy", "timestamp", LocalDateTime.now()));
        
        // 系统资源检查
        Map<String, Object> systemResources = checkSystemResources();
        health.put("systemResources", systemResources);
        
        // 错误率检查
        double errorRate = calculateErrorRate();
        String errorStatus = errorRate < 0.05 ? "healthy" : errorRate < 0.2 ? "warning" : "critical";
        health.put("errorRate", Map.of("value", errorRate, "status", errorStatus, "timestamp", LocalDateTime.now()));
        
        // 整体状态评估
        boolean overallHealthy = dbHealthy && parseServiceHealthy && errorRate < 0.2;
        health.put("overall", Map.of("status", overallHealthy ? "healthy" : "unhealthy", "timestamp", LocalDateTime.now()));
        
        return health;
    }
    
    /**
     * 获取告警信息
     */
    public List<Map<String, Object>> getActiveAlerts() {
        List<Map<String, Object>> alerts = new ArrayList<>();
        
        // 错误率告警
        double errorRate = calculateErrorRate();
        if (errorRate > 0.2) {
            alerts.add(Map.of(
                "type", "ERROR_RATE_HIGH",
                "severity", "critical",
                "message", "错误率过高: " + String.format("%.2f%%", errorRate * 100),
                "timestamp", LocalDateTime.now()
            ));
        } else if (errorRate > 0.1) {
            alerts.add(Map.of(
                "type", "ERROR_RATE_WARNING",
                "severity", "warning", 
                "message", "错误率偏高: " + String.format("%.2f%%", errorRate * 100),
                "timestamp", LocalDateTime.now()
            ));
        }
        
        // 请求量异常告警
        long recentRequests = getRecentRequestCount();
        if (recentRequests == 0) {
            alerts.add(Map.of(
                "type", "NO_REQUESTS",
                "severity", "warning",
                "message", "最近5分钟无请求",
                "timestamp", LocalDateTime.now()
            ));
        }
        
        return alerts;
    }
    
    /**
     * 定时更新监控指标
     */
    @Scheduled(fixedRate = 60000) // 每分钟执行一次
    public void updateMonitoringMetrics() {
        try {
            // 更新系统健康状态
            systemHealth.putAll(performHealthCheck());
            
            // 更新活跃告警
            List<Map<String, Object>> alerts = getActiveAlerts();
            activeAlerts.clear();
            for (Map<String, Object> alert : alerts) {
                activeAlerts.add((String) alert.get("type"));
            }
            
            // 记录日志
            log.debug("监控指标已更新: 总请求数={}, 成功数={}, 失败数={}, 成功率={}%", 
                     totalRequests.get(), successRequests.get(), failedRequests.get(), 
                     calculateSuccessRate() * 100);
            
        } catch (Exception e) {
            log.error("更新监控指标失败", e);
        }
    }
    
    /**
     * 定时清理历史数据
     */
    @Scheduled(cron = "0 0 2 * * ?") // 每天凌晨2点执行
    public void cleanupHistoricalData() {
        try {
            log.info("开始清理历史监控数据");
            
            // 重置计数器（可以考虑保留一些历史数据）
            if (totalRequests.get() > 1000000) { // 当总请求数超过100万时重置
                long oldTotal = totalRequests.getAndSet(0);
                long oldSuccess = successRequests.getAndSet(0);
                long oldFailed = failedRequests.getAndSet(0);
                
                log.info("监控计数器已重置: 总请求数从{}重置, 成功数从{}重置, 失败数从{}重置", 
                        oldTotal, oldSuccess, oldFailed);
            }
            
            // 清理错误计数
            errorCounts.clear();
            
        } catch (Exception e) {
            log.error("清理历史数据失败", e);
        }
    }
    
    // 私有辅助方法
    
    private void updateRealtimeMetrics() {
        realtimeMetrics.put("currentQPS", calculateCurrentQPS());
        realtimeMetrics.put("avgResponseTime", calculateAvgResponseTime());
        realtimeMetrics.put("lastUpdateTime", LocalDateTime.now());
    }
    
    private double calculateSuccessRate() {
        long total = totalRequests.get();
        if (total == 0) return 1.0;
        return (double) successRequests.get() / total;
    }
    
    private double calculateErrorRate() {
        long total = totalRequests.get();
        if (total == 0) return 0.0;
        return (double) failedRequests.get() / total;
    }
    
    private Map<String, Long> getErrorDistribution() {
        Map<String, Long> distribution = new HashMap<>();
        for (Map.Entry<String, AtomicLong> entry : errorCounts.entrySet()) {
            distribution.put(entry.getKey(), entry.getValue().get());
        }
        return distribution;
    }
    
    private boolean checkDatabaseHealth() {
        try {
            // 尝试查询数据库
            long count = parseRecordService.count();
            return true;
        } catch (Exception e) {
            log.warn("数据库健康检查失败", e);
            return false;
        }
    }
    
    private boolean checkParseServiceHealth() {
        // 检查解析服务是否正常
        // 这里可以添加具体的检查逻辑
        return true;
    }
    
    private Map<String, Object> checkSystemResources() {
        Map<String, Object> resources = new HashMap<>();
        
        // JVM内存使用情况
        Runtime runtime = Runtime.getRuntime();
        long totalMemory = runtime.totalMemory();
        long freeMemory = runtime.freeMemory();
        long usedMemory = totalMemory - freeMemory;
        double memoryUsage = (double) usedMemory / totalMemory;
        
        resources.put("jvm", Map.of(
            "totalMemory", totalMemory,
            "freeMemory", freeMemory,
            "usedMemory", usedMemory,
            "memoryUsage", memoryUsage,
            "status", memoryUsage > 0.9 ? "critical" : memoryUsage > 0.7 ? "warning" : "healthy"
        ));
        
        return resources;
    }
    
    private double calculateCurrentQPS() {
        // 简化实现，实际应该基于时间窗口计算
        return 0.0;
    }
    
    private double calculateAvgResponseTime() {
        // 简化实现，需要记录响应时间数据
        return 0.0;
    }
    
    private long getRecentRequestCount() {
        // 获取最近5分钟的请求数
        // 简化实现，返回当前计数
        return totalRequests.get();
    }
    
    private Map<Integer, Long> analyzeHourlyActivity(LocalDateTime startTime, LocalDateTime endTime) {
        // 分析每小时的活跃度
        Map<Integer, Long> hourlyStats = new HashMap<>();
        for (int i = 0; i < 24; i++) {
            hourlyStats.put(i, 0L);
        }
        return hourlyStats;
    }
    
    private Map<String, Object> analyzeUserRetention(LocalDateTime startTime, LocalDateTime endTime) {
        // 用户留存分析
        Map<String, Object> retention = new HashMap<>();
        retention.put("dailyRetention", 0.0);
        retention.put("weeklyRetention", 0.0);
        retention.put("monthlyRetention", 0.0);
        return retention;
    }
    
    private List<Map<String, Object>> analyzeSuccessRateTrend(LocalDateTime startTime, LocalDateTime endTime) {
        // 成功率趋势分析
        return new ArrayList<>();
    }
    
    private Map<String, Long> analyzeDevicePreference(LocalDateTime startTime, LocalDateTime endTime) {
        // 设备偏好分析
        return new HashMap<>();
    }
    
    private Map<String, Object> analyzeGeographicalDistribution(LocalDateTime startTime, LocalDateTime endTime) {
        // 地理分布分析
        Map<String, Object> geo = new HashMap<>();
        geo.put("countries", new HashMap<String, Long>());
        geo.put("regions", new HashMap<String, Long>());
        geo.put("cities", new HashMap<String, Long>());
        return geo;
    }
}